# -*- coding: utf-8 -*-

from odoo import models, fields, api
from datetime import datetime, timedelta
from odoo.exceptions import UserError



class Account(models.Model):
    _inherit = 'account.journal'

    to_private = fields.Boolean('对私')

class BorrowFeeExt(models.Model):
    _inherit = 'borrow.fee'

    expense_expense_id = fields.Many2one('expense.expense', string="出差申请单")

class Expense(models.Model):
    _name = 'expense.expense'
    _inherit = ['mail.thread', 'common.state.methods']
    _order = 'id desc'


    write_uid = fields.Many2one('res.users', string='最后更新者', index=True,
                                readonly=True, track_visibility='onchange')
    write_date = fields.Datetime(string='最近修改时间', readonly=True,
                                 track_visibility='onchange')
    name = fields.Char(string=u"出差申请单单号",)
    start_time = fields.Date(string=u"起始时间")
    end_time = fields.Date(string=u"结束时间")
    travel_days = fields.Integer(string=u"出行天数", compute="_compute_travel_days",
         store=True, digits=(1, 1))
    destination = fields.Char("目的地")
    # client = fields.Many2one("res.partner", string=u"客户")
    project_name = fields.Char('项目名称',
         states={'approve': [('readonly', True)],
                 'ceo_approve': [('readonly', True)],
                 'draft': [('readonly', True)]})
    travel_way = fields.Many2one('expense.travel', u"出行方式")
    total_expense = fields.Float(compute="_compute_total", string=u"费用总计", store=True, )
    purpose = fields.Text(string=u"出差事宜", required=True)
    summary = fields.Text(string=u"总结")
    lines = fields.One2many("expense.line", "order_id", u"费用明细")
    fee_date = fields.Date('费用发生日期')
    state = fields.Selection([
        ('ready', '待提交'),
        ('draft', u"部门经理审批"),
        ('approve', u"销售总监审批"),
        ('ceo_approve', '总经理审批'),
        ('pass', u"通过"),
        ('summarize', u"总结"),('cancel', '取消') ], string='Status', copy=False, index=True,
        store=True, default="ready", help="Status of the expense.")
    travel_fee_line = fields.One2many('expense.chart.line', 'expense_id',
        string='差旅明细')
    borrow_fee_ids = fields.One2many('borrow.fee', 'expense_expense_id', string="借款申请")
    borrow_fee_count = fields.Integer('借款单数量', compute="_compute_borrow_fee_count", store=True)
    request_user = fields.Many2one('hr.employee', string="申请人", default=lambda self:self.env.user.employee_ids[0])
    responsible_employee = fields.Many2many('hr.employee', string='明细承担人', store=True,
                                            compute="_compute_responsible_employee")

    @api.multi
    def unlink(self):
        for rec in self:
            if rec.state != 'ready':
                raise UserError('不能删除处于非草稿状态的出差申请单据！')
        return super(Expense, self).unlink()

    @api.depends('lines', 'lines.employee_id_2')
    def _compute_responsible_employee(self):
        for order in self:
            ids = []
            for line in order.lines:
                if line.employee_id_2:
                    ids.append(line.employee_id_2.id)
            order.responsible_employee = [(6, 0, ids)]


    @api.depends('borrow_fee_ids')
    def _compute_borrow_fee_count(self):
        for order in self:
            if order.borrow_fee_ids:
                fee_ids = order.borrow_fee_ids.filtered(lambda x:x.state != 'cancelled')
                order.borrow_fee_count = len(fee_ids)

    @api.multi
    def borrow_fee_action(self):
        # 跳转到借款单form视图
        self.ensure_one()
        form_view_id = self.env.ref('expense.borrow_fee_form_view').id
        action = {
            'type': 'ir.actions.act_window',
            'views': [(form_view_id, 'form')],
            'view_mode': 'form',
            'name': '借款申请',
            'res_model': 'borrow.fee',
            'context':{'default_expense_expense_id':self.id,
                       'borrow_id_editable':True,
                       'default_request_user':self.env.user.id}
            # 'domain':[('origin_evection_expense', '=', self.id)]
            # 'res_model':'consult.fee.request.line'
            }
        return action

    @api.multi
    def action_view_return_fee(self):
        # 跳转到借款单列表
        self.ensure_one()
        form_view_id = self.env.ref('expense.borrow_fee_form_view').id
        action = {
            'type': 'ir.actions.act_window',
            # 'views': [(form_view_id, 'form')],
            'view_mode': 'tree,form',
            'name': '借款申请',
            'res_model': 'borrow.fee',
            # 'context':{'default_expense_expense_id':self.id}
            'domain':[('expense_expense_id', '=', self.id)]
            # 'res_model':'consult.fee.request.line'
            }
        return action

    @api.model
    def create(self,vals):
        vals['name']=self.env['ir.sequence'].next_by_code('errands_expense.sequence')
        return super(Expense,self).create(vals)

    @api.depends('lines.price')
    def _compute_total(self):
        total = 0.00
        for order in self:
            for record in order.lines:
                total += record.price
        self.total_expense = total

    @api.multi
    def action_submit(self):
        if self.state == 'ready':
            self.write({"state": "draft"})

    @api.multi
    def action_draft(self):
        self.write({"state": "approve"})

    @api.multi
    def action_approve(self):
        self.write({"state": "ceo_approve"})

    @api.multi
    def action_ceo_approve(self):
        if self.state == 'ceo_approve':
            self.write({"state": "pass"})

    @api.multi
    def action_expense_reimbursement(self):
        # values = {'product_id': 1,
        #        'quantity':1 ,
        #        'name':'',
        #        'unit_amount':self.total_expense,
        # }
        # 检查有没有写总结
        if not self.summary:
            raise UserError('请填写总结')
        if not self.lines:
            raise UserError('请添加至少一项费用明细！')
        if self.state != 'pass':
            return

        values = {
            'date':datetime.now(),
            'employee_id':self.env.user.id,
            'employee_id_2':self.env.user.id,
            'expense_expense_id':self.id,
            'title':self.project_name,
            'employee_id': self.request_user.id,
            'expense_lines':[(6, 0, self.lines.ids)]
            }
        expense_id = self.env['evection.expense'].create(values).id
        for line in self.lines:
            line.evection_expense_id = expense_id
            # line.employee_id_2 = self.env.user.id
        self.state = 'summarize'

        action = self.env.ref('expense.evection_expense_action').read()[0]
        res = self.env.ref('expense.evection_expense_form_view', False)
        action['views'] = [(res and res.id or False, 'form')]
        action['res_id'] = expense_id

        return action

    @api.depends('start_time', 'end_time')
    def _compute_travel_days(self):
        for order in self:
            if order.start_time and order.end_time:
                order.travel_days = (order.end_time - order.start_time + timedelta(days=1)).days

    @api.multi
    def action_view_evection_expense(self):
        form_view_id = self.env.ref('expense.evection_expense_form_view').id
        action = {
            'type': 'ir.actions.act_window',
            # 'views': [(form_view_id, 'form')],
            'view_mode': 'tree,form',
            'name': '报销',
            'res_model': 'evection.expense',
            'domain':[('expense_expense_id', '=', self.id)]
            # 'res_model':'consult.fee.request.line'
            }
        return action

    # @api.multi
    # def chart_confirm(self):
    #     # 根据差旅明细，生成费用明细，在提交出差申请时调用此方法，
    #     # 也可以在出差申请前手动调用
    #     for order in self:
    #         if order.state != 'pass':
    #             return
    #         for line in order.travel_fee_line:
    #             if not line.is_applied:
    #                 # 创建费用明细
    #                 travel_vals = {
    #                     'name':line.product_id.id,
    #                     'price':line.amount,
    #                     'order_id':self.id,
    #                     'partner_id':line.partner_id.id,
    #                     'employee_id_2':line.employee_id_2.id,
    #                      }
    #                 self.env['expense.line'].create(travel_vals)

    #                 # 创建出差补贴
    #                 travel_product = self.env['product.product'].search([('name', '=', '出差补助'),
    #                     ('can_be_expensed', '=', True)])
    #                 if not travel_product:
    #                     raise UserError('没有找到名为“出差补助”的费用产品，请创建一个')
    #                 travel_product = travel_product[0]

    #                 allowance_vals = {
    #                     'name':travel_product.id,
    #                     'price':line.butie_fee,
    #                     'order_id':self.id,
    #                     'partner_id':line.partner_id.id,
    #                     'employee_id_2':line.employee_id_2.id,
    #                      }
    #                 self.env['expense.line'].create(allowance_vals)
    #                 line.is_applied = True


class TravelWay(models.Model):
    _name = 'expense.travel'
    _rec_name = 'travel_way'

    travel_way = fields.Char(string=u"出行方式")


class TravelDestination(models.Model):
    _name = 'expense.destination'
    _rec_name = 'destination'

    destination = fields.Char(string=u"目的地")


class ExpenseLine(models.Model):
    _name = "expense.line"
    _description = u"日志"
    _order = 'id desc'

    @api.model
    def _get_employee(self):
        employee = self.env['hr.employee'].search([('user_id', '=', self._uid)])
        if employee:
            return employee.ids[0]
        else:
            return None

    name = fields.Many2one('product.product', )
    partner_id = fields.Many2one('res.partner')
    price = fields.Float(u"金额", default=0.0, digits=(8,2))
    employee_id_2 = fields.Many2one('hr.employee', string="承担人", default=_get_employee)
    order_id = fields.Many2one("expense.expense", u"费用啊", ondelete='cascade', index=True)
    evection_expense_id = fields.Many2one('evection.expense', string="所属费用单")
    description = fields.Char('备注')
    department = fields.Many2one('hr.department', store=True, compute="_compute_department")
    occur_date = fields.Date(u'费用发生日期')
    request_order_id = fields.Many2one('evection.expense.request', string="申请单")
    request_state = fields.Selection([
        ('requested', '已支付'),
        ('will_requested', '待支付'),
        ('wait_cash', '待出纳审核'),
        ('not_requested', '未支付'),
        ], string='支付状态', copy=False, index=True, store=True,
        default="not_requested", compute="_compute_request_state")
    start_location = fields.Char( '起始地点')
    end_location = fields.Char('结束地点')
    start_time = fields.Date('起始时间')
    end_time = fields.Date('结束时间')
    duartion = fields.Integer('天数', compute="_compute_duartion", store=True)
    ticket_quantity = fields.Integer('单据张数')
    request_employee_id = fields.Many2one('hr.employee', string="申请人", store=True,
                                          compute="_compute_request_employee_id")
    borrow_fee_id = fields.Many2one('borrow.fee', string='来自借款单')
    show_name = fields.Char('单号', compute="_compute_show_name", store=True)
    who_push_it = fields.Many2one('hr.employee', string="提交人")
    state = fields.Selection([
        ('draft', u'待提交'),
        ('department_approval', u'部门经理审批'),
        ('financial_approval', u'财务审批'),
        ('manager_approval', u'总经办审批'),
        ('finance_done', '财务确认'),
        ('done', u'已完成'),
        ('cancel', '取消'),
        ], string='状态', copy=False, store=True,
        compute="_compute_state")

    @api.multi
    def unlink(self):
        if self.filtered(lambda r: r.state not in ['draft', 'cancel']):
            raise UserError('不能删除付款提交单据！')
        return super(ExpenseLine, self).unlink()

    @api.depends('borrow_fee_id', 'evection_expense_id','borrow_fee_id.state', 'evection_expense_id.state')
    def _compute_state(self):
        for order in self:
            if order.evection_expense_id:
                order.state = order.evection_expense_id.state
            elif order.borrow_fee_id and order.borrow_fee_id.state in ['done', 'clear', 'boss_approve']:
                order.state = 'done'
            else:
                order.state = 'draft'

    @api.depends('borrow_fee_id', 'evection_expense_id', 'evection_expense_id.name')
    def _compute_show_name(self):
        for order in self:
            if order.evection_expense_id:
                order.show_name = order.evection_expense_id.name
            elif order.borrow_fee_id:
                order.show_name = order.borrow_fee_id.name

    @api.depends('evection_expense_id.employee_id')
    def _compute_request_employee_id(self):
        for order in self:
            if order.evection_expense_id:
                order.request_employee_id = order.evection_expense_id.employee_id
            elif order.borrow_fee_id:
                order.request_employee_id = order.borrow_fee_id.request_user.employee_ids[0]

    @api.depends('start_time', 'end_time')
    def _compute_duartion(self):
        for line in self:
            if line.start_time and line.end_time:
                duration = fields.Datetime.from_string(line.end_time) - fields.Datetime.from_string(line.start_time) + timedelta(days=1)
                line.duartion = int(duration.days)

    @api.depends('request_order_id', 'request_order_id.state')
    def _compute_request_state(self):
        for line in self:
            if not line.request_order_id or line.request_order_id.state == 'cancel':
                line.request_state = 'not_requested'
            elif line.request_order_id.state == 'draft':
                line.request_state = 'will_requested'
            elif line.request_order_id.state == 'cash':
                line.request_state = 'wait_cash'
            elif line.request_order_id.state == 'confirm':
                line.request_state = 'requested'

    @api.depends('employee_id_2')
    def _compute_department(self):
        for line in self:
            line.department = line.employee_id_2.department_id.id

class HrExpenseInherit(models.Model):
    _inherit = "hr.expense"

    client = fields.Many2one("res.partner",string=u"客户")
    state = fields.Selection([
        ('draft', u'待提交'),
        ('department_approval', u'部门经理审批'),
        ('financial_approval', u'财务审批'),
        ('manager_approval', u'总经办审批'),
        ('unpaid', u'待支付'),
        ('done', u'已付款')
    ], string='Status', copy=False, index=True, readonly=True, store=True, default="draft")

    @api.multi
    def action_draft(self):
        self.write({"state": "department_approval"})

    @api.multi
    def action_department_approval(self):
        self.write({"state": "financial_approval"})

    @api.multi
    def action_financial_approval(self):
        self.write({"state": "manager_approval"})

    @api.multi
    def action_manager_approval(self):
        self.write({"state": "unpaid"})

    @api.multi
    def action_done(self):
        action = self.env.ref('expense.expense_account_action').read()[0]
        return action
